

(defun lisp-update(update-type l loc-type content)
  (my-copy update-type l loc-type content))
(defun my-copy(update-type l loc-type content)
  (if (atom l)
      l								
      (let ((a (car l))(t-val (cadr loc-type)))
	(if (atom a)
	    (cond ((and (eql a 'defun)(eql (cadr l) t-val)(eql (car loc-type) 'func-define))
		   (list-update update-type 'func-define l content))
		  ((and (eql a t-val)(eql (car loc-type) 'func-call))
		   (list-update update-type 'func-call l content))
		  (t (cons (my-copy update-type  a loc-type content)(my-copy update-type (cdr l) loc-type content))))
	    (cons (my-copy update-type (car l) loc-type content)(my-copy update-type (cdr l) loc-type content))))))
(defun list-update(update-type mytype l val)
   (dolist (m val)
    (let ((f-name (car l))(loc (car m))(v (cadr m))(line (nth 2 m)))
      (cond ((eql mytype 'func-define)
	     (cond ((eql loc 'head)(cond ((eql update-type 'add)
					  (setf l (add-list l 3 v)))
					 ((eql update-type 'del)
					  (setf l (del-list l 3)))
					 ((eql update-type 'edit)
					  (setf l (edit-list l 3 v)))
					 (t (format t  "[~a] not defined for func-define head.~%" update-type))))
		   ((eql loc 'tail)(cond ((eql update-type 'add)(setf l (add-list l (length l) v)))
					 ((eql update-type 'del)(setf l (del-list l (1- (length l)))))
					 ((eql update-type 'edit)(setf l (edit-list l (1- (length l)) v)))
					 (t (format t t "[~a] not defined for func-define tail.~%" update-type))))
		   ((eql loc 'body)(cond ((and (eql update-type 'add)(integerp line))(setf l (add-list l (+ 2 line) v)))
					 ((and (eql update-type 'del)(integerp line))(setf l (del-list l (+ 2 line))))
					 ((and (eql update-type 'edit)(integerp line)(> line 0))(setf l (edit-list l (+ 2 line) v)))
					 ((and (eql update-type 'edit)(integerp line)(= line 0))(setf l (edit-body l 3 v)))
					 (t (format t  "[~a] not defined for func-define body OR line[~a] be defined nil.~%" update-type line))))
		   ((eql loc 'name)(if (eql update-type 'edit)
				       (setf l (edit-list l 1 v))
				     (format t "func-define name only be edit[~a].~%" update-type)))
		   ((eql loc 'para)(cond ((and (eql update-type 'add)(integerp line))(setf (nth 2 l) (add-list (nth 2 l) line v)))
					 ((and (eql update-type 'del)(integerp line))(setf (nth 2 l) (del-list (nth 2 l) line)))
					 ((and (eql update-type 'edit)(integerp line))(setf (nth 2 l) (edit-list (nth 2 l) line v)))
					 (t (format t  "[~a] not defined for func-define para OR line[%d] be defined nil.~%" update-type line))))
					      
		 
		   (t (format t  "func-define edit: [~a] not be defined.~%" loc))))
	    ((eql mytype 'func-call)
	     (cond ((eql loc 'head)(cond ((eql update-type 'add)(setf l (list 'progn v l)))
					 (t (format t t "[~a] not defined for func-call head.~%" update-type))))
		   ((eql loc 'tail)(cond ((eql update-type 'add)(setf l (list 'progn l v)))
					 (t (format t t "[~a] not defined for func-call tail.~%" update-type))))
		   ((eql loc 'body)(cond ((eql update-type 'del) (setf l nil))
					 ((eql update-type 'edit) (setf l v))
					 (t (format t  "[~a] not defined for func-call body.~%" update-type))))
		   ((eql loc 'name)(if (eql update-type 'edit)
				       (setf l (edit-list l 0 v))
				     (format t "func-call name only be edit[~a].~%" update-type)))
		   ((eql loc 'para)(cond ((and (eql update-type 'add)(integerp line)(> line 0))(setf l (add-list l line v)))
					 ((and (eql update-type 'del)(integerp line)(> line 0))(setf l (del-list l line)))
					 ((and (eql update-type 'edit)(integerp line)(> line 0))(setf l (edit-list l line v)))
					 ;((and (eql update-type 'loc)(integerp line))(nth line l))
					 (t (format t  "[~a] not defined for func-call para OR line[~a] be defined nil.~%" update-type line))))
		   ((and (eql loc 'var)
			 (or (eql f-name 'let)
			     (eql f-name 'do)
			     (eql f-name 'dolist)
			     (eql f-name 'dotimes)
			     (eql f-name 'do*)
;;add new macro here			     
			     (eql f-name 'let*)))
		    (cond ((and (eql update-type 'add)(integerp line))(setf (cadr l) (add-list (cadr l) line v)))
			  ((and (eql update-type 'del)(integerp line))(setf (cadr l) (del-list (cadr l) line)))
			  ((and (eql update-type 'edit)(integerp line))(setf (cadr l) (edit-list (cadr l) line v)))
			  (t (format t  "[~a] not defined for func-call var OR line[~a] be defined nil.~%" update-type line))))
		   ((and (eql loc 'var-value)
			 (or (eql f-name 'let)
			     (eql f-name 'do)
			     (eql f-name 'dolist)
			     (eql f-name 'dotimes)
			     (eql f-name 'do*)
;;add new macro here			     
			     (eql f-name 'let*)))
		    (let ((val-num (nth 3 m)))
		      
		      (cond ((and (eql update-type 'add)(integerp line))(setf (cadr (cadr (nth line (cadr l))))  (add-list (cadr (cadr (nth line (cadr l)))) 0 v)))
			    ((and (eql update-type 'del)(integerp line)(integerp val-num))(setf (cadr (cadr (nth line (cadr l)))) (del-list (cadr (cadr (nth line (cadr l)))) val-num)))
			    ((and (eql update-type 'edit)(integerp line)(integerp val-num))(setf (cadr (cadr (nth line (cadr l)))) (edit-list (cadr (cadr (nth line (cadr l)))) val-num v)))
			    (t (format t  "[~a] not defined for func-call var-value OR the [~a] var and the [~a] value be defined nil.~%" update-type line val-num)))))
		   (t (format t  "func-call edit:[~a] not be defined.~%" loc)))))))
   l)

(defun add-list(l loc val)
  (if (null l)
     (list  val)
  (let ((ll nil))
    (dotimes (i (length l))
      (if (= i loc)
	  (setf ll (concatenate 'list ll (list val) (list (nth i l))))
	  (setf ll (concatenate 'list ll (list (nth i l))))))
    (if (= loc (length l))
	(setf ll (concatenate 'list ll (list val))))
    ll)))
(defun del-list(l loc)
  (let ((ll nil))
    (dotimes (i (length l))
      (if (= i loc)
	  nil
	  (setf ll (concatenate 'list ll (list (nth i l))))))
    ll))
(defun edit-list(l loc val)
  (let ((ll nil))
    (dotimes (i (length l))
      (if (= i loc)
	  (setf ll (concatenate 'list ll (list val)))
	  (setf ll (concatenate 'list ll (list (nth i l))))))
    ll))
(defun edit-body(l loc val)
  (let ((ll nil)(len (length l)))
    (dotimes (i len)
      (cond ((= i loc)(setf ll (concatenate 'list ll (list val))))
	    ((< i loc)(setf ll (concatenate 'list ll (list (nth i l)))))))
    ll))

(defvar current-function-name "test")
(defvar current-function  'test)
(defvar l nil);; it be used in interactive mode.
(defun write-list(l)
  (with-open-file (fw (concatenate 'string current-function-name ".lisp") :direction :output :if-exists :supersede)
    (if (atom (car l)) (write l :stream fw) (dolist (i x)(write i :stream fw)))))
(defmacro _add(l loc-type content)
  `(setf ,l (lisp-update 'add ,l ,loc-type ,content)))
(defmacro _del(l loc-type con-loc con-line &optional val-num)
  `(setf ,l (lisp-update 'del ,l ,loc-type (list (list ,con-loc nil ,con-line,val-num)))))
(defmacro _edit(l loc-type content)
  `(setf ,l (lisp-update 'edit ,l ,loc-type ,content)))


 

(defun _f(name &optional val-pair-list)
  (let ((ll nil))
    (if val-pair-list (progn
			(setq ll '(defun f-name(in) (let ((v-list nil))(if (null v-list) nil (dolist (i v-list) (if (equal in (car i))(return (cadr i))))))))
			(setf ll (_edit ll '(func-call let) `((var (v-list ',val-pair-list) 0)))))
      (setq ll '(defun f-name() nil)))
    (setf ll (_edit ll '(func-define f-name) `((name ,name))))
    (setf current-function-name (string name))
    (setf current-function name)
    (setq l ll)))
(defun _fc(name &optional val-pair-list)
  (if (atom (car l))
  (setf l (list l)))
  (let ((ll nil))
    (if val-pair-list (progn
			(setq ll '(defun f-name(in) (let ((v-list nil))(if (null v-list) nil (dolist (i v-list) (if (equal in (car i))(return (cadr i))))))))
			(setf ll (_edit ll '(func-call let) `((var (v-list ',val-pair-list) 0)))))
      (setq ll '(defun f-name() nil)))
    (setf ll (_edit ll '(func-define f-name) `((name ,name))))
    (setf current-function-name (string name))
    (setf current-function name)
    (push ll l)))
(defmacro _add_pair(l val-pair)
  `(_add l '(func-call let) '((var-value ,val-pair 0 0))))
;;(_add_pair l (2 4)) omit '

(defvar example-list nil)
(defvar func-count-list nil)
(defun _example(&key func in out)
  (if (null func) (setf func current-function))
  (let ((pos (position func example-list :key #'car)))
    (if pos (push (list in out) (cadr (nth pos example-list)))
	(push (list func (list (list in out))) example-list))
    (format t "NO ~a.~%" (length (cadr (nth (position func example-list :key #'car) example-list))))))
(defun _test(&optional func)
  (eval l)
  (if (null func) (setf func current-function))
  (let ((pos (position func example-list :key #'car))(test-list nil))
    (if pos (progn (setf test-list (cadr (nth pos example-list)))
		   (dotimes (i (length test-list))
		     (if (eql (apply func (car (nth i test-list))) (cadr (nth i test-list)))
			 (format t "[~a]Test NO ~a[~a]: pass.~%" func i (nth i test-list))
			 (format t "[~a]Test NO ~a[~a]: error.~%" func i (nth i test-list)))))
	(format t "[~a] function test data not found in example-list.~%" func))))
    
(defmacro _=(a b) `(setf ,a ,b))
(defmacro _add_para(f para)
 `(_add l '(func-define ,f) ',(let ((ll nil)) (dotimes (i (length para)) (push  (list 'para (nth i para) i) ll)) (reverse ll))))
(defmacro _add_body(f body)
  `(_edit l '(func-define ,f) '((body ,body 1))))

  
  
    
